#!/usr/bin/env python
#-*- coding:utf-8 -*-
import os,sys
from wwpy.io.Sock import SockIO
from wwpy.net.Asker import Asker
from wwpy.util.Logger import Logger
from wwpy.util.ThreadPool import ThreadPool
from wwpy.net.Wcp import WcpParser,WcpCreator
from wwpy.tms.conf.node import worker_nodes

class Manager(object):
    
    def __init__(self,request=None,sock=None,timeout=None,*args,**kwargs):
        self.logger=Logger()
        self.request=request
        self.sock=sock
        self.timeout=timeout
        self.nodes=worker_nodes
        self.parser=WcpParser(self.request).parse()
        self.parser['pkg']='wwpy.tms.lib.Actuator'
        self.parser['cls']='Actuator'
        
    @staticmethod
    def operations():
        return ('START_SCHED','STOP_SCHED','RESTART_SCHED','SHOW_TASK_RECORDS','SHOW_FAILED_TASKS','REDO_FAILED_TASKS')
        
    def ask(self,node,question):
        asker=Asker(host=node.host,port=node.port)
        asker.call()
        if(asker.is_connected):
            answer=asker.argue(question)
            return answer
        else:
            self.logger.info("Node %s cann't be connected." % str(node))
            return 0
        
    def reply(self,answer):
        io=SockIO(sock=self.sock,timeout=self.timeout)
        io.write(answer)
    
    def to_do(self,func):
        self.logger.info("Manager begin to %s task." % func)
        tp=ThreadPool(max_threads=len(self.nodes))
        request=WcpCreator(func=func,**self.parser).create()
        for node in self.nodes:
            tp.put(self.ask,node,request)
        tp.wait()
        for out in tp.outs():
            result=out[-1]
            if not result:
                return 0
            print result
            sys.stdout.flush()
        return 1
    
    def do(self,*args,**kwargs):
        operation=self.parser.get('operation','')
        operations=self.operations()
        assert operation in operations,'No defined operation %s in %s.' % (operation,operations)
        func=operation.lower()
        if operation in operations:
            state=self.to_do(func)
            self.reply('Finished task: %s' % operation)
            return state
        self.reply('Nothing to do.')
        return False
    